using System.Net.NetworkInformation;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace FileTransfer.Client.Test;

[TestClass]
public class NetworkConnectivityTest
{
    private readonly ILogger<NetworkConnectivityTest> _logger;

    public NetworkConnectivityTest()
    {
        var loggerFactory = LoggerFactory.Create(builder =>
            builder.AddConsole().SetMinimumLevel(LogLevel.Information)
        );
        _logger = loggerFactory.CreateLogger<NetworkConnectivityTest>();
    }

    /// <summary>
    /// 测试设备是否可达（类似Java代码中的isReachable方法）
    /// </summary>
    /// <param name="ipAddress">IP地址</param>
    /// <param name="timeout">超时时间（毫秒）</param>
    /// <returns>是否可达</returns>
    public async Task<bool> IsReachableAsync(string ipAddress, int timeout = 3000)
    {
        try
        {
            using var ping = new Ping();
            _logger.LogInformation("正在尝试连接到设备：{IpAddress}", ipAddress);

            var reply = await ping.SendPingAsync(ipAddress, timeout);
            var isReachable = reply.Status == IPStatus.Success;

            if (isReachable)
            {
                _logger.LogInformation(
                    "设备 {IpAddress} 可达，响应时间：{RoundTripTime}ms",
                    ipAddress,
                    reply.RoundtripTime
                );
            }
            else
            {
                _logger.LogWarning(
                    "设备 {IpAddress} 不可达，状态：{Status}",
                    ipAddress,
                    reply.Status
                );
            }

            return isReachable;
        }
        catch (Exception e)
        {
            _logger.LogError(e, "无法连接到设备：{IpAddress}", ipAddress);
            return false;
        }
    }

    [TestMethod]
    public async Task TestLocalHostConnectivity()
    {
        // 测试本地环回地址
        var isReachable = await IsReachableAsync("127.0.0.1");
        Assert.IsTrue(isReachable, "本地环回地址应该是可达的");
    }

    [TestMethod]
    public async Task TestNetworkConnectivity()
    {
        // 测试公共DNS服务器（Google DNS）
        var isReachable = await IsReachableAsync("8.8.8.8");
        // 注意：这个测试可能因为网络环境而失败，所以我们只记录结果
        _logger.LogInformation("Google DNS (8.8.8.8) 可达性测试结果：{IsReachable}", isReachable);
    }

    [TestMethod]
    public async Task TestSpecificDeviceConnectivity()
    {
        // 测试特定设备（类似Java代码中的示例）
        string deviceIp = "192.168.6.248";
        var isReachable = await IsReachableAsync(deviceIp);

        // 记录结果但不断言，因为这个IP可能不存在
        _logger.LogInformation(
            "设备 {DeviceIp} 可达性测试结果：{IsReachable}",
            deviceIp,
            isReachable
        );
    }

    [DataTestMethod]
    [DataRow("127.0.0.1", true)] // 本地环回，应该总是可达
    [DataRow("169.254.1.1", false)] // 链路本地地址，通常不可达
    public async Task TestConnectivityWithExpectedResults(string ipAddress, bool expectedReachable)
    {
        var isReachable = await IsReachableAsync(ipAddress);

        if (expectedReachable)
        {
            Assert.IsTrue(isReachable, $"预期 {ipAddress} 应该可达");
        }
        else
        {
            // 对于预期不可达的地址，我们只记录结果，不强制断言
            _logger.LogInformation(
                "地址 {IpAddress} 的可达性测试结果：{IsReachable}（预期：{Expected}）",
                ipAddress,
                isReachable,
                expectedReachable
            );
        }
    }
}
